﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;

using SharedGenomics.Core;

namespace SharedGenomics.Workbench.Annotations
{
    public class AnnotationRequestPipeline
    {
        private IList<IAnnotationRequestStage> _stages;

        public AnnotationRequestPipeline()
        {
            this._stages = new List<IAnnotationRequestStage>();
        }

        public void AddRequestStage(IAnnotationRequestStage stage)
        {
            stage.ThrowIfNull("stage");
            ExceptionHelper.ThrowIf<InvalidOperationException>(this.IsFixed, "Cannot add stage to fixed pipeline");

            this._stages.Add(stage);
        }

        public void AddRequestStage<TStage>() where TStage : IAnnotationRequestStage, new()
        {
            this.AddRequestStage(new TStage());
        }

        public void Fix()
        {
            this.IsFixed = true;
        }

        public void Execute(AnnotationRequestInfo requestInfo)
        {
            requestInfo.ThrowIfNull("requestInfo");
            ExceptionHelper.ThrowIf<InvalidOperationException>(!this.IsFixed, "Cannot execute non-fixed pipeline");

            if (this._stages.Count > 0)
            {
                //create new context for request and traversal strategy
                AnnotationRequestContext context = new AnnotationRequestContext(requestInfo.Key, requestInfo.RootValue);
                var traversalStrategy = new AnnotationRequestPipelineTraversalStrategy(this._stages);

                //pass control off to first stage
                this._stages[0].Process(context, traversalStrategy);
            }
        }

        public bool IsFixed { get; private set; }
    }
}
